package com.zhhtech.zhh.ui.tool.image.select.service.impl

import android.content.Context
import androidx.lifecycle.Observer
import com.alibaba.fastjson.JSON
import com.luck.picture.lib.basic.PictureSelector
import com.luck.picture.lib.config.SelectMimeType
import com.luck.picture.lib.config.SelectModeConfig
import com.luck.picture.lib.entity.LocalMedia
import com.luck.picture.lib.interfaces.OnResultCallbackListener
import com.zhhtech.zhh.api.core.ApiComplete
import com.zhhtech.zhh.api.core.ApiError
import com.zhhtech.zhh.api.core.ApiProcess
import com.zhhtech.zhh.api.core.FirmException
import com.zhhtech.zhh.ui.api.ApiObserver
import com.zhhtech.zhh.ui.ext.DefaultLifecycleObserver
import com.zhhtech.zhh.ui.tool.image.select.service.IImageSelect
import com.zhhtech.zhh.ui.tool.image.select.service.ImageSelectIntercept
import com.zhhtech.zhh.ui.tool.image.select.service.ImageUploadUBuilder
import com.zhhtech.zhh.ui.tool.image.select.service.intercept.QiNiuIntercept
import com.zhhtech.zhh.ui.utils.Logger
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.suspendCancellableCoroutine
import kotlin.coroutines.resume
import kotlin.coroutines.resumeWithException

abstract class AbstractImageSelect : IImageSelect, DefaultLifecycleObserver {
    //    imageSelectIntercepts: (MutableList<ImageSelectIntercept>.() -> Unit)? = null
    private lateinit var mBuilder: ImageUploadUBuilder
    private var mImageSelectIntercepts: MutableList<ImageSelectIntercept>? = null

    abstract val context: Context?
    abstract val pictureSelector: PictureSelector
    abstract fun <T> launchUI(
        block: suspend CoroutineScope.() -> T,
        apiObserver: Observer<ApiProcess<T>>? = null,
        error: ApiError? = null,
        complete: ApiComplete? = null,
    )

    init {
        mImageSelectIntercepts = mutableListOf<ImageSelectIntercept>().apply {
            QiNiuIntercept()
        }
    }

    override fun selectImage(config: (ImageUploadUBuilder.() -> Unit)?) {
        mBuilder = config?.let { ImageUploadUBuilder().apply(it) } ?: ImageUploadUBuilder()
        launchUI({
            var result = openGallery()
            mImageSelectIntercepts?.takeIf { it.isNotEmpty() }?.forEach {
                result = it.intercept(result)
            }
            result?.forEach {
                Logger.e("result==>" + it::class.java.name)
            }
            result
        }, ApiObserver(context) { result ->
            mBuilder.onUploadSuccessListener?.invoke(result)
        }, error = {
            mBuilder.onCancelSuccessListener?.invoke()
        })
    }

    private suspend fun openGallery() =
        suspendCancellableCoroutine<MutableList<com.zhhtech.zhh.ui.tool.image.select.domain.ImageSelectBean>?> { coroutine ->
            pictureSelector
                .openGallery(SelectMimeType.ofImage())
                .setImageEngine(com.zhhtech.zhh.ui.tool.image.select.engine.GlideEngine.createGlideEngine())
                //.setCompressEngine(ImageCompressEngine.imageCompressEngine)
                // .setSandboxFileEngine(MeSandboxFileEngine.meSandboxFileEngine)
                .setQueryOnlyMimeType("image/png", "image/jpeg", "image/jpg")
                .setMaxSelectNum(mBuilder.selectCount)
                .setImageSpanCount(mBuilder.columnCount)
                .isDisplayCamera(true)
                .isPreviewImage(true)
                .setSelectionMode(if (mBuilder.isMultipleChoice) SelectModeConfig.MULTIPLE else SelectModeConfig.SINGLE)
                .forResult(object : OnResultCallbackListener<LocalMedia> {
                    override fun onResult(result: ArrayList<LocalMedia>?) {
                        coroutine.resume(result?.mapTo(mutableListOf()) {
                            JSON.toJavaObject(JSON.toJSON(it) as JSON?, com.zhhtech.zhh.ui.tool.image.select.domain.ImageSelectBean::class.java)
                        })
                    }

                    override fun onCancel() {
                        coroutine.resumeWithException(FirmException("", -1, null))
                    }

                })
        }
}